package com.traffic.between.service;

import java.security.MessageDigest;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.traffic.between.config.BetweenProperties;

public class ShangTongServiceImpl {
	private static Logger logger = Logger.getLogger(ShangTongServiceImpl.class);
	public static ShangTongServiceImpl service = new ShangTongServiceImpl();

	private static String STKJ_ORDER_URL = BetweenProperties.STKJ_ORDER_URL;
	private static String STKJ_ORDERSTATUS_URL = BetweenProperties.STKJ_ORDERSTATUS_URL;
	private static String STKJ_APPKEY = BetweenProperties.STKJ_APPKEY;
	private static String STKJ_SECURITYKEY = BetweenProperties.STKJ_SECURITYKEY;

	public String order(String productId, String phoneNo, String cstmOrderNo) {
	
		String time = String.valueOf(new Date().getTime());

		Map<String, String> params = new HashMap<String, String>();
		params.put("account", STKJ_APPKEY);
		params.put("action", "Charge");
		params.put("phone", phoneNo);
		// 流量包大小，产品编码
		params.put("size", productId);
		// 充值范围。0 :全国; 1 :省内;
		params.put("range", "0");
		params.put("timeStamp", time);
		// 获取sign
		String sign = createSign(params, "order");

		HttpClient httpClient = new HttpClient();
		httpClient.getHostConfiguration().setHost("http://api.liuliang.net.cn", 80, "http");

		PostMethod post = new PostMethod(STKJ_ORDER_URL);
		post.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
		NameValuePair[] param = { new NameValuePair("phone", phoneNo), new NameValuePair("timeStamp", time),
				new NameValuePair("range", "0"), new NameValuePair("action", "Charge"),
				new NameValuePair("account", STKJ_APPKEY), new NameValuePair("size", productId),
				new NameValuePair("orderNo", cstmOrderNo), new NameValuePair("sign", sign) };
		post.setRequestBody(param);
		post.releaseConnection();

		HttpMethod method = (HttpMethod) post;
		logger.info("between- 尚通科技订购请求参数: params"+param);
		String response = null;

		try {
			httpClient.executeMethod(method);
			response = method.getResponseBodyAsString();
			logger.info("between- 尚通科技流量订购请求时的响应数据是: " + response);
		} catch (Exception e) {
			logger.error("between- 尚通科技流量订购请求时的响应异常: " + e);
		}

		return response;
	}


	/**
	 * 根据订单id调用尚通查询订单状态
	 * 
	 * @param cstmOrderNo
	 * @return
	 */
	public String orderStatus(String cstmOrderNo) {
		logger.info("between- 尚通科技订购请求参数: cstmOrderNo = " + cstmOrderNo);
		String time = String.valueOf(new Date().getTime());
		Map<String, String> params = new HashMap<String, String>();
		params.put("account", STKJ_APPKEY);
		params.put("action", "Query");
		params.put("orderID", cstmOrderNo);
		params.put("timeStamp", time);

		// 请求签名。（加密小写32位）apiKey+account=XXXXX&action=Charge&phone=XXXXX&range=0&size=10&timeStamp=********+apiKey
		String sign = createSign(params, "orderStatus");

		HttpClient httpClient = new HttpClient();
		httpClient.getHostConfiguration().setHost("http://api.liuliang.net.cn", 80, "http");

		PostMethod post = new PostMethod(STKJ_ORDERSTATUS_URL);
		post.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");

		NameValuePair[] param = { new NameValuePair("account", STKJ_APPKEY), new NameValuePair("action", "Query"),
				new NameValuePair("orderID", cstmOrderNo), new NameValuePair("timeStamp", time),
				new NameValuePair("sign", sign) };
		post.setRequestBody(param);
		post.releaseConnection();

		HttpMethod method = (HttpMethod) post;

		String response = null;
		try {
			httpClient.executeMethod(method);
			response = method.getResponseBodyAsString();
			logger.info("between- 尚通科技流量订购请求时的响应数据是: " + response);
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("between- 尚通科技流量订购请求时的响应异常: " + e);
		}

		return response;

	}

	/**
	 * 根据排序后的map 生成sign 按照格式key=value&key=value 拼接后，将用户获取的apikey 拼接在参数的首尾进行md5加密
	 * 
	 * @param paramMap
	 * @return
	 */
	private static String createSign(Map<String, String> paramMap, String str) {

		// 排序map，升序
		if (paramMap == null || paramMap.isEmpty()) {
			return null;
		}
		Map<String, String> sortMap = new TreeMap<String, String>(new MapKeyComparator());
		sortMap.putAll(paramMap);

		// 拼接map 按照格式key=value&key=value 拼接
		StringBuffer stringBuffer = new StringBuffer();
		for (Iterator<String> it = sortMap.keySet().iterator(); it.hasNext();) {
			String key = it.next();
			String value = sortMap.get(key);
			if (StringUtils.isNotEmpty(value)) {
				stringBuffer.append(key + "=").append(value + "&");
			}
		}
		stringBuffer.deleteCharAt(stringBuffer.length() - 1);
		String waitStr = STKJ_SECURITYKEY + stringBuffer + STKJ_SECURITYKEY;
		logger.info("between -尚通科技sign待加密字符串 <>" + str + "       :" + waitStr);

		// md5加密 用于生成sign
		MessageDigest messageDigest = null;
		StringBuffer md5StrBuff = new StringBuffer();
		try {
			messageDigest = MessageDigest.getInstance("MD5");
			messageDigest.reset();
			messageDigest.update(waitStr.getBytes("UTF-8"));

			byte[] byteArray = messageDigest.digest();
			for (int i = 0; i < byteArray.length; i++) {
				if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)
					md5StrBuff.append("0").append(Integer.toHexString(0xFF & byteArray[i]));
				else
					md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));
			}
		} catch (Exception e) {
			throw new RuntimeException();
		}
		return md5StrBuff.toString().toLowerCase();// 字母小写
	}

}

class MapKeyComparator implements Comparator<String> {
	public int compare(String str1, String str2) {
		return str1.compareTo(str2);
	}
}